package cn.est.controller;

import cn.est.constants.Constants;
import cn.est.dto.Result;
import cn.est.pojo.Users;
import cn.est.service.SmsLogService;
import cn.est.service.TokenService;
import cn.est.service.UsersService;
import cn.est.utils.EstSQLException;
import cn.est.utils.RedisUtil;
import cn.est.utils.ResultUtils;
import cn.est.vo.TokenVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Api("user")  //swagger注解
@RestController
@RequestMapping("/api/")
public class LoginController {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    SmsLogService smsLogService;

    @Autowired
    UsersService userService;

    @Autowired
    TokenService tokenService;


    @ApiOperation(value = "发送短信接口",produces = "application/json",notes = "发送短信")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone",value = "手机号码",required = true,dataType = "String"),
            @ApiImplicitParam(name = "codeType",value = "验证码类型：0注册，1修改密码，2通知-下单通知",required = true,dataType = "int"),
    })
    @PostMapping("/sms/verifycode")
    public Result verifyCode(String phone, Integer codeType){
        //1、判断手机号码是否正确
        if (!checkPhone(phone)){
            return ResultUtils.returnFail("手机号码输入不正确","200001");
        }
        //2、判断短信是否正确
        if (!checkCodeType(codeType.toString())){
            return ResultUtils.returnFail("验证码输入不正确","200001");
        }
        //3、验证码发送的频率
        if (!checksmsCode(phone,codeType)){
            return ResultUtils.returnFail("验证码输入太频繁，请稍后再试","200001");
        }
        //4、发送短信
        try {
            smsLogService.sendMessage(phone,codeType);
        } catch (Exception e) {
            return ResultUtils.returnFail("系统异常，请重新发送");
        }
        return ResultUtils.returnSuccess();
    }


    @ApiOperation(value = "手机验证码注册或登录接口",produces="application/json",notes ="使用手机验证码进行注册、登录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name="phone",value = "手机号码",required = true,dataType = "string"),
            @ApiImplicitParam(name="sms",value = "验证码",required = true,dataType = "string")
    })
    @PostMapping("/user/login/sms")
    public Result login(@RequestParam("phone")String phone, @RequestParam("sms") String sms){
        //1.验证手机号码是否正确
        if(!checkPhone(phone)){
            return ResultUtils.returnFail("手机号码错误，请重新输入","200001");
        }
        //2.校验验证码是否存在在redis中
        String key =Constants.Redis.PREFIX_SMS+"0"+":"+phone;
        String keyvalue= (String) redisUtil.get(key);
        if(keyvalue==null||!keyvalue.equals(sms)){
            return ResultUtils.returnFail("验证码有误，请重新输入","2004");
        }
        //3.实现登录功能
        TokenVo tokenVo = null;
        try {
            Users user= userService.loginByPhone(phone);
            //4.生成系统令牌
             tokenVo =tokenService.genenrateToken(user);


             //5.保存到Redis中
            tokenService.saveToken(tokenVo.getToken(),user);
        } catch (EstSQLException e) {
            e.printStackTrace();
            return  ResultUtils.returnFail("数据库异常,注册失败","20005");
        }
        return ResultUtils.returnDataSuccess(tokenVo);
    }






    //判断手机号
    private boolean checkPhone(String phone){
        boolean flag = false;
        if (phone != null){
            //判断是否符合正则表达式 matches：字符串内置方法
            flag = phone.matches(Constants.PHONE_REGSTR);
        }
        return flag;
    }

    //判断验证码类型
    private boolean checkCodeType(String codeType){
        boolean flag = false;
        if (codeType != null){
            if (codeType.equals("0") || codeType.equals("1") || codeType.equals("2")){
                flag = true;
            }
        }
        return flag;
    }

    //判断验证码发送频率
    private boolean checksmsCode(String phone,Integer codeType){
        String key = Constants.Redis.PREFIX_SMS+codeType+":"+phone;
        //根据手机号码把验证码从redis中取出查看是否还存在
        String code = (String) redisUtil.get(key);
        if (code != null){
            return false;
        }
        return true;
    }
}
